package com.md2ppt.animation;

import com.md2ppt.config.PresentationConfig;
import com.aspose.slides.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.HashMap;
import java.util.List;

/**
 * 动画引擎核心类
 * 负责协调Aspose.Slides动画处理
 */
public class AnimationEngine {
    
    private static final Logger logger = LoggerFactory.getLogger(AnimationEngine.class);
    
    private final PresentationConfig config;
    private final EffectMapper effectMapper;
    private final TimingController timingController;
    
    public AnimationEngine(PresentationConfig config) {
        this.config = config;
        this.effectMapper = new EffectMapper();
        this.timingController = new TimingController();
        
        logger.info("初始化动画引擎: {}", config.settings().animationEngine());
    }
    
    /**
     * 为幻灯片应用动画效果
     */
    public void applyAnimations(ISlide slide, List<PresentationConfig.AnimationConfig> animations) {
        if (animations == null || animations.isEmpty()) {
            logger.debug("幻灯片 {} 无动画配置", slide.getSlideNumber());
            return;
        }
        
        logger.info("为幻灯片 {} 应用 {} 个动画效果", slide.getSlideNumber(), animations.size());
        
        var animationSequence = slide.getTimeline().getMainSequence();
        
        for (var animConfig : animations) {
            try {
                applyAnimationToSlide(slide, animConfig, animationSequence);
            } catch (Exception e) {
                logger.error("动画应用失败: {}", animConfig.effectType(), e);
                // 继续处理其他动画
            }
        }
    }
    
    /**
     * 为单个元素应用动画
     */
    private void applyAnimationToSlide(ISlide slide, PresentationConfig.AnimationConfig animConfig, 
                                     ISequence animationSequence) {
        
        // 查找目标元素
        var targetShape = findTargetShape(slide, animConfig.targetElement());
        if (targetShape == null) {
            logger.warn("未找到目标元素: {}", animConfig.targetElement());
            return;
        }
        
        // 映射动画效果类型
        var effectType = effectMapper.mapEffectType(animConfig.effectType());
        if (effectType == null) {
            logger.warn("不支持的动画效果类型: {}", animConfig.effectType());
            return;
        }
        
        // 创建动画效果
        var effect = animationSequence.addEffect(targetShape, effectType, 
                                                EffectSubtype.None, EffectTriggerType.AfterPrevious);
        
        // 应用时间配置
        if (animConfig.timing() != null) {
            timingController.applyTiming(effect, animConfig.timing());
        }
        
        // 应用自定义属性
        if (animConfig.properties() != null) {
            applyAnimationProperties(effect, animConfig.properties());
        }
        
        logger.debug("成功应用动画: {} -> {}", animConfig.targetElement(), animConfig.effectType());
    }
    
    /**
     * 查找目标形状
     */
    private IAutoShape findTargetShape(ISlide slide, String targetElement) {
        for (var shape : slide.getShapes()) {
            if (shape instanceof IAutoShape autoShape) {
                // 通过形状名称或文本内容匹配
                if (targetElement.equals(autoShape.getName()) || 
                    (autoShape.getTextFrame() != null && 
                     autoShape.getTextFrame().getText().contains(targetElement))) {
                    return autoShape;
                }
            }
        }
        return null;
    }
    
    /**
     * 应用动画属性
     */
    private void applyAnimationProperties(IEffect effect, Map<String, Object> properties) {
        for (var entry : properties.entrySet()) {
            switch (entry.getKey().toLowerCase()) {
                case "direction" -> applyDirection(effect, entry.getValue());
                case "speed" -> applySpeed(effect, entry.getValue());
                case "smooth_start" -> applySmoothStart(effect, entry.getValue());
                case "smooth_end" -> applySmoothEnd(effect, entry.getValue());
                default -> logger.debug("未知动画属性: {}", entry.getKey());
            }
        }
    }
    
    private void applyDirection(IEffect effect, Object value) {
        if (value instanceof String direction) {
            // 根据方向字符串设置动画方向
            logger.debug("设置动画方向: {}", direction);
        }
    }
    
    private void applySpeed(IEffect effect, Object value) {
        if (value instanceof Number speed) {
            logger.debug("设置动画速度: {}", speed);
        }
    }
    
    private void applySmoothStart(IEffect effect, Object value) {
        if (value instanceof Boolean smooth) {
            logger.debug("设置平滑开始: {}", smooth);
        }
    }
    
    private void applySmoothEnd(IEffect effect, Object value) {
        if (value instanceof Boolean smooth) {
            logger.debug("设置平滑结束: {}", smooth);
        }
    }
    
    /**
     * 获取动画统计信息
     */
    public AnimationStatistics getStatistics() {
        return new AnimationStatistics(0, 0, 0); // 待实现
    }
    
    /**
     * 动画统计记录
     */
    public record AnimationStatistics(
        int totalEffects,
        int successfulEffects,
        int failedEffects
    ) {}
    
    /**
     * 动画效果映射器
     */
    private static class EffectMapper {
        private final Map<String, Integer> effectTypeMap;
        
        public EffectMapper() {
            this.effectTypeMap = new HashMap<>();
            initializeEffectMappings();
        }
        
        private void initializeEffectMappings() {
            // 入场动画 (Entrance Effects)
            effectTypeMap.put("fade_in", EffectType.Fade);
            effectTypeMap.put("fly_in", EffectType.Fly);
            effectTypeMap.put("wipe", EffectType.Wipe);
            effectTypeMap.put("split", EffectType.Split);
            effectTypeMap.put("wheel", EffectType.Wheel);
            effectTypeMap.put("random_bars", EffectType.RandomBars);
            effectTypeMap.put("grow_and_turn", EffectType.GrowAndTurn);
            effectTypeMap.put("zoom", EffectType.Zoom);
            effectTypeMap.put("swivel", EffectType.Swivel);
            effectTypeMap.put("bounce", EffectType.Bounce);
            effectTypeMap.put("blinds", EffectType.Blinds);
            effectTypeMap.put("box", EffectType.Box);
            effectTypeMap.put("checkerboard", EffectType.Checkerboard);
            effectTypeMap.put("circle", EffectType.Circle);
            effectTypeMap.put("crawl_in", EffectType.CrawlIn);
            effectTypeMap.put("diamond", EffectType.Diamond);
            effectTypeMap.put("dissolve_in", EffectType.DissolveIn);
            effectTypeMap.put("flash_once", EffectType.FlashOnce);
            effectTypeMap.put("peek_in", EffectType.PeekIn);
            effectTypeMap.put("plus", EffectType.Plus);
            effectTypeMap.put("strips", EffectType.Strips);
            
            // 强调动画 (Emphasis Effects)
            effectTypeMap.put("pulse", EffectType.Pulse);
            effectTypeMap.put("color_pulse", EffectType.ColorPulse);
            effectTypeMap.put("teeter", EffectType.Teeter);
            effectTypeMap.put("spin", EffectType.Spin);
            effectTypeMap.put("grow_shrink", EffectType.GrowShrink);
            effectTypeMap.put("desaturate", EffectType.Desaturate);
            effectTypeMap.put("darken", EffectType.Darken);
            effectTypeMap.put("lighten", EffectType.Lighten);
            effectTypeMap.put("transparency", EffectType.Transparency);
            effectTypeMap.put("object_color", EffectType.ObjectColor);
            effectTypeMap.put("complementary_color", EffectType.ComplementaryColor);
            effectTypeMap.put("complementary_color2", EffectType.ComplementaryColor2);
            effectTypeMap.put("contrasting_color", EffectType.ContrastingColor);
            effectTypeMap.put("brush_on_color", EffectType.BrushOnColor);
            effectTypeMap.put("wave", EffectType.Wave);
            effectTypeMap.put("reveal_underline", EffectType.RevealUnderline);
            effectTypeMap.put("bold_flash", EffectType.BoldFlash);
            effectTypeMap.put("bold_reveal", EffectType.BoldReveal);
            
            // 退场动画 (Exit Effects)
            effectTypeMap.put("fade_out", EffectType.Fade);
            effectTypeMap.put("fly_out", EffectType.Fly);
            effectTypeMap.put("wipe_out", EffectType.Wipe);
            effectTypeMap.put("disappear", EffectType.Disappear);
            effectTypeMap.put("random_effects", EffectType.RandomEffects);
            effectTypeMap.put("spiral_out", EffectType.SpiralOut);
            effectTypeMap.put("contract", EffectType.Contract);
            effectTypeMap.put("collapse", EffectType.Collapse);
            
            // 路径动画 (Motion Path Effects)
            effectTypeMap.put("custom_path", EffectType.PathUser);
            effectTypeMap.put("arc_down", EffectType.ArcDown);
            effectTypeMap.put("arc_left", EffectType.ArcLeft);
            effectTypeMap.put("arc_right", EffectType.ArcRight);
            effectTypeMap.put("arc_up", EffectType.ArcUp);
            effectTypeMap.put("bounce_left", EffectType.BounceLeft);
            effectTypeMap.put("bounce_right", EffectType.BounceRight);
            effectTypeMap.put("curvy_left", EffectType.CurvyLeft);
            effectTypeMap.put("curvy_right", EffectType.CurvyRight);
            effectTypeMap.put("decaying_wave", EffectType.DecayingWave);
            effectTypeMap.put("diagonal_down_right", EffectType.DiagonalDownRight);
            effectTypeMap.put("diagonal_up_right", EffectType.DiagonalUpRight);
            effectTypeMap.put("down", EffectType.Down);
            effectTypeMap.put("funnel", EffectType.Funnel);
            effectTypeMap.put("spring", EffectType.Spring);
            effectTypeMap.put("stairs_down", EffectType.StairsDown);
            effectTypeMap.put("turn_down", EffectType.TurnDown);
            effectTypeMap.put("turn_up", EffectType.TurnUp);
            effectTypeMap.put("turn_up_right", EffectType.TurnUpRight);
            effectTypeMap.put("up", EffectType.Up);
            effectTypeMap.put("right", EffectType.Right);
            effectTypeMap.put("left", EffectType.Left);
        }
        
        public Integer mapEffectType(String effectName) {
            return effectTypeMap.get(effectName.toLowerCase());
        }
    }
    
    /**
     * 时间控制器
     */
    private static class TimingController {
        
        public void applyTiming(IEffect effect, PresentationConfig.AnimationTiming timing) {
            // 设置持续时间
            effect.getTiming().setDuration((float) timing.duration());
            
            // 设置延迟
            if (timing.startDelay() > 0) {
                effect.getTiming().setTriggerDelayTime((float) timing.startDelay());
            }
            
            // 设置重复次数
            if (timing.repeatCount() > 1) {
                effect.getTiming().setRepeatCount(timing.repeatCount());
            }
            
            // 设置自动反向
            if (timing.autoReverse()) {
                effect.getTiming().setAutoReverse(true);
            }
            
            logger.debug("应用时间配置: 持续时间={}s, 延迟={}s, 重复={}次", 
                        timing.duration(), timing.startDelay(), timing.repeatCount());
        }
    }
}